using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.IO;

namespace Smled
{
    public class Tile
    {
        private Image tileImage;
        private string tileName;
        private int tileNum;
        private TileSet parentSet;
        private int offX;
        private int offY;
        private String fChar = "";
        private INIGroup iniDesc = null;

        public int OffsetX { get { return offX; } set { offX = value; } }
        public int OffsetY { get { return offY; } set { offY = value; } }
        public int ID { get { return tileNum; } set { tileNum = value; } }
        //public String FileString { get { return fChar; } set { fChar = value; } }
        public String Name { get { return tileName; } set { tileName = value; } }
        public String FileChar { get { return fChar; } set { fChar = value; } }

        public Tile()
        {
            tileImage = null;
            tileName = "default-name";
            tileNum = -1;
        }

        public Tile(TileSet Parent)
        {
            parentSet = Parent;
            tileNum = parentSet.GetGreaterOrEqual(0);
            tileImage = null;
            tileName = "default-name";
        }

        public Tile(TileSet Parent, INIGroup source)
        {
            iniDesc = source;
            parentSet = Parent;
            tileNum = parentSet.GetGreaterOrEqual(0);
            tileImage = null;
            readSource();
        }

        private void readSource()
        {
            tileNum = iniDesc.getInteger("ID", 0);
            tileName = iniDesc.getString("Name", "default-name");
            fChar = iniDesc.getString("FileChar", ".");
            offX = iniDesc.getInteger("OffsetX", 0);
            offY = iniDesc.getInteger("OffsetY", 0);
        }

        private void updateSource()
        {
            if (iniDesc == null) iniDesc = new INIGroup("Tile");
            iniDesc.set("ID", tileNum.ToString());
            iniDesc.set("Name", tileName);
            iniDesc.set("FileChar", fChar);
            iniDesc.set("OffsetX", offX.ToString());
            iniDesc.set("OffsetY", offY.ToString());
        }

        public INIGroup Source
        {
            get
            {
                return iniDesc;
            }
        }

        public Tile(String FileName, string theName, int theNumber)
        {
            Image b = Image.FromFile(FileName);
            if (b == null) return;

            if (!InitTile(b, theName, theNumber)) return;
        }

        public Tile(Image SourceImage, string theName, int theNumber)
        {
            if (!InitTile(SourceImage, theName, theNumber)) return;
        }

        private bool InitTile(Image SourceImage, string theName, int theNumber)
        {
            if (SourceImage == null) return false;

            Image b = new Bitmap(SourceImage.Width, SourceImage.Height);
            Graphics g = Graphics.FromImage(b);
            //g.DrawImage(SourceImage, new Rectangle(0, 0, 32, 32));
            g.DrawImage(SourceImage, new Rectangle(0, 0, SourceImage.Width, SourceImage.Height));
            g.Flush();
            g.Dispose();
            tileImage = b;

            tileName = theName;
            tileNum = theNumber;
            return true;
        }

        public bool SaveTileImage(string FileName)
        {
            try
            {
                tileImage.Save(FileName, System.Drawing.Imaging.ImageFormat.Png);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool WriteToStream(Stream s)
        {
            try
            {
                StreamWriter sw = new StreamWriter(s);
                sw.WriteLine(tileNum);
                sw.WriteLine(tileName);
                sw.WriteLine(fChar);
                sw.WriteLine(offX);
                sw.WriteLine(offY);
                //sw.Close();
                return true;
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message);
                return false;
            }
        }

        public bool WriteMeta(Stream s)
        {
            try
            {
                StreamWriter sw = new StreamWriter(s);
                updateSource();
                iniDesc.WriteToStream(sw);
                return true;
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message);
                return false;
            }
        }

        public bool WriteMeta(StreamWriter sw)
        {
            try
            {
                updateSource();
                iniDesc.WriteToStream(sw);
                return true;
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message);
                return false;
            }
        }

        public bool WriteToStreamWriter(StreamWriter sw)
        {
            try
            {
                //StreamWriter sw = new StreamWriter(s);
                sw.WriteLine(tileNum);
                sw.WriteLine(tileName);
                sw.WriteLine(fChar);
                sw.WriteLine(offX);
                sw.WriteLine(offY);
                //sw.Close();
                return true;
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message);
                return false;
            }
        }

        public Image TileImage
        {
            get { return tileImage; }
            set
            {
                InitTile(value, tileName, tileNum);
            }
        }
    }
}
